﻿#include "scenemodel.h"

#include <QIcon>

#include "../core/feature.h"
#include "../core/room.h"

SceneModel::SceneModel(Feature *root, QObject *parent)
    : QAbstractItemModel(parent), m_root(root) {
  m_buildingIcon = new QIcon(":/src/icon/building.png");
  m_floorIcon = new QIcon(":/src/icon/floor.png");
  m_funcAreaIcon = new QIcon(":/src/icon/shop.png");
  m_pubPointIcon = new QIcon(":/src/icon/pubpoint.png");
}

SceneModel::~SceneModel() {
  delete m_buildingIcon;
  delete m_floorIcon;
  delete m_funcAreaIcon;
  delete m_pubPointIcon;
  m_root = NULL;
}

Qt::ItemFlags SceneModel::flags(const QModelIndex &index) const {
  if (!index.isValid()) {
    return Qt::ItemIsEnabled;
  }
  return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
}

QModelIndex SceneModel::index(int row, int column,
                              const QModelIndex &parent) const {
  if (m_root == NULL) {
    return QModelIndex();
  }

  Feature *parentObject = m_root;
  if (parent.isValid()) {
    parentObject = static_cast<Feature *>(parent.internalPointer());
  }

  if (parentObject == NULL) {
    return QModelIndex();
  }

  QList<QObject *> childList = parentObject->children();
  int rowCount = childList.count();

  if ((row >= 0) && (row < rowCount)) {
    QObject *child = childList.at(row);
    return createIndex(row, column, (void *)child);
  } else {
    return QModelIndex();
  }
}

QModelIndex SceneModel::parent(const QModelIndex &child) const {
  if (m_root == NULL) {
    return QModelIndex();
  }

  if (!child.isValid()) {
    return QModelIndex();
  }

  Feature *childObject = static_cast<Feature *>(child.internalPointer());
  if (childObject == NULL) {
    return QModelIndex();
  }

  Feature *parentObject = dynamic_cast<Feature *>(childObject->parentItem());
  if (parentObject == NULL) {
    return QModelIndex();
  }

  if (parentObject == m_root) {
    return QModelIndex();
  }

  int row = 0;
  Feature *grandParentObject = dynamic_cast<Feature *>(parentObject->parent());
  if (grandParentObject == NULL) {
    return QModelIndex();
  }

  row = grandParentObject->children().indexOf(parentObject);

  return createIndex(row, 0, parentObject);
}

int SceneModel::rowCount(const QModelIndex &parent) const {
  if (m_root == NULL) {
    return 0;
  }

  Feature *parentObject = m_root;
  if (parent.isValid()) {
    parentObject = static_cast<Feature *>(parent.internalPointer());
  }

  if (parentObject == NULL) {
    return 0;
  }

  QList<QObject *> childList = parentObject->children();
  int count = childList.count();

  return count;
}

int SceneModel::columnCount(const QModelIndex &parent) const {
  Q_UNUSED(parent)
  return 1;
}

QVariant SceneModel::headerData(int section, Qt::Orientation orientation,
                                int role) const {
  if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
    if (section == 0)
      return QString("Scene");
  }
  return QVariant();
}

QVariant SceneModel::data(const QModelIndex &index, int role) const {
  if (!index.isValid()) {
    return QVariant();
  }

  if (role == Qt::DecorationRole) {
    if (index.column() == 0) {
      QString className = static_cast<Feature *>(index.internalPointer())
                              ->metaObject()
                              ->className();
      if (className == "Building") {
        return *m_buildingIcon;
      } else if (className == "Floor") {
        return *m_floorIcon;
      } else if (className == "Room") {
        return *m_funcAreaIcon;
      } else if (className == "PubPoint") {
        return *m_pubPointIcon;
      }
    }
  } else if (role == Qt::DisplayRole) {
    if (index.column() == 0) {
      Feature *feature = static_cast<Feature *>(index.internalPointer());
      if (feature != NULL) {
        QString className = feature->metaObject()->className();
        if (className == "Room") {
          Room *room = dynamic_cast<Room *>(feature);
          if (room->dianpingId() != 0 && room->dianpingId() != -1) {
            return room->objectName() + '(' +
                   QString::number(room->dianpingId()) + ')';
          }
        }
        return feature->objectName();
      }
    }
  }

  return QVariant();
}

QModelIndex SceneModel::featureIndex(Feature *feature) const {
  if (m_root == NULL) {
    return QModelIndex();
  }

  if (feature == NULL) {
    return QModelIndex();
  }

  Feature *parentObject = dynamic_cast<Feature *>(feature->parentItem());

  if (parentObject == NULL) {
    return QModelIndex();
  }

  int row = 0;
  row = parentObject->children().indexOf(feature);

  return createIndex(row, 0, (void *)feature);
}
